#include "StdAfx.h"
#include "paramhandler.h"
#include "tokenizer.h"

#pragma warning(disable : 4996)


CParamHandler::CParamHandler(void)
{
	Reset();
}

CParamHandler::~CParamHandler(void)
{
}


vector<float> CParamHandler::GetFloatVector(const string &s)
{
	//
	// TODO not the most efficient way to get the vector....
	// pass as an argument a reference to the output vector
	CTokenizer tokenizer(s);
	vector<float> tokens;

	while (tokenizer.nextToken())
	{
		tokens.push_back( (float)atof( tokenizer.getToken().c_str() ) );
	}
	return tokens;
}

bool CParamHandler::HasValue(const string &param)
{
	map<string, string>::iterator iter = m_values.find(param);

	if( iter== m_values.end())
	{
		// not such a parameter in m_values....	
		return false;
	}

	string s = iter->second;
	if( s == "")
	{
		// parameter exists but has no value.....	
		return false;
	}
	return true;  
}

float* CParamHandler::GetFloatPtr(const string &s)
{
	float* pf=0;

	CTokenizer tokenizer(s);
	vector<float> tokens;

	while (tokenizer.nextToken())
	{
		tokens.push_back( (float)atof( tokenizer.getToken().c_str() ) );
	}

	pf = new float[(int)tokens.size()];

	vector<float>::iterator fIter,fEnd;
	fEnd = tokens.end();
	int i=0;

	for (fIter=tokens.begin(); fIter!=fEnd; fIter++,i++)
	{
		pf[i] = *fIter;
	}

	return pf;
}


Vector3 CParamHandler::GetVector(const string &s)
{
	CTokenizer tokenizer(s);
	Vector3 vec;
	int i=0;
	while (tokenizer.nextToken())
	{
		if(i>2)
		{
#ifdef LOG_PARAMHANDLER
			Log("Oops, this vector has more than 3 parameters\n");
#endif
			break;
		}

		vec[i] = (float)atof(tokenizer.getToken().c_str());
		i++;
	}

	return vec;
}


float CParamHandler::GetFloat(const string &s)
{
	return (float)atof(s.c_str());
}


int CParamHandler::GetInt(const string &s)
{
	return atoi(s.c_str());
}


vector<float*> CParamHandler::GetTwoFloatArrays(const string &s)
{
	CTokenizer tokenizer(s);
	vector<float> vec;

	while (tokenizer.nextToken())
	{
		vec.push_back((float)atof(tokenizer.getToken().c_str()));
	}
	
	
	vector<float*> v;
	vector<float>::iterator fIter,fEnd;
	fEnd = vec.end();
	int i=0;
	bool which=0;
	int k=0;
	for (fIter=vec.begin(); fIter!=fEnd; fIter++,i++)
	{
		if(!which)
			v.push_back(new float[2]);
		v[k][which] = *fIter;

		if(which)
			++k;

		which = !which;	
	}
	return v;
}


char** CParamHandler::GetCharPtrPtr(const string &s, int &no)
{
	CTokenizer tokenizer(s);
	vector<string> tokens;

	while (tokenizer.nextToken())
	{
		tokens.push_back(tokenizer.getToken());
	}

	char** rv = new char*[(int)tokens.size()];

	for (int i=0; i<(int)tokens.size(); i++)
	{
		rv[i] = new char[tokens[i].length()];
		strcpy(rv[i],tokens[i].c_str());
	}

	no = (int)tokens.size();
	return rv;
}



void CParamHandler::AddToValue(const string &param,const string &valueToAdd)
{
	if (IsTrue(param))
	{
		m_values[param] += valueToAdd.c_str();
		m_values[param] += " ";
	}
}
void CParamHandler::SetAllFalse()
{
	m_parameters["segments"]=false;
	m_parameters["lengths"]=false;
	m_parameters["widths"]=false;
	m_parameters["heights"]=false;
	m_parameters["tailtype"]=false;
	m_parameters["muscles"]=false;
	m_parameters["particle"]=false;
	m_parameters["connection"]=false;
	m_parameters["waterpress"]=false;
	m_parameters["stabilizer"]=false;
	m_parameters["acrobatics"]=false;
	m_parameters["position"]=false;
	m_parameters["scale"]=false;
	m_parameters["looses"]=false;                        

	m_parameters["texturescale"]=false;
	m_parameters["texturemove"]=false;
	m_parameters["texturepath"]=false;
	m_parameters["textureextra"]=false;      

	m_parameters["turnwaypoints"]=false;
	m_parameters["turntimes"]=false;
	m_parameters["turnextra"]=false;
	m_parameters["movewaypoints"]=false;
	m_parameters["moveextra"]=false;
	m_parameters["movetimes"]=false;
	m_parameters["updownwaypoints"]=false;
	m_parameters["updownextra"]=false;
	m_parameters["updowntimes"]=false;

	//-----------NEW------------------
	m_parameters["rootindex"]=false;	
	m_parameters["modelfile"]=false;	
	m_parameters["debug"]=false;
	m_parameters["rotation"]=false;


	m_parameters["speed"];
	m_parameters["type"];
	m_parameters["gender"];
	m_parameters["alive"];
	m_parameters["stamina"];
	m_parameters["hunger"];
	m_parameters["digestion_rate"];
	m_parameters["nutritional_value"];
	m_parameters["feeding_distance"];
	m_parameters["see_radius"];
	m_parameters["hear_radius"];
	m_parameters["smell_radius"];
	m_parameters["agility"];
	m_parameters["age"];
	m_parameters["life_span"];
	m_parameters["prefered_separation"];
	m_parameters["keepaway_distance"];
	m_parameters["reproduct_rate"];
	/*map<string,bool>::iterator mIter,mEnd;
	mEnd = m_parameters.end();
	mIter = m_parameters.begin();	

	while(mIter!=mEnd)
	{
		(*mIter).second = false;
		mIter++;
	}*/
}
void CParamHandler::Reset()
{
	m_values["segments"]="";
	m_values["lengths"]="";
	m_values["widths"]="";
	m_values["heights"]="";
	m_values["tailtype"]="";
	m_values["muscles"]="";
	m_values["particle"]="";
	m_values["connection"]="";
	m_values["waterpress"]="";
	m_values["stabilizer"]="";
	m_values["acrobatics"]="";
	m_values["position"]="";
	m_values["scale"]="";
	m_values["texturepath"]="";
	m_values["textureextra"]="";            
	m_values["looses"]="";
	m_values["texturescale"]="";
	m_values["texturemove"]="";
	m_values["turnwaypoints"]="";
	m_values["turntimes"]="";
	m_values["turnextra"]="";
	m_values["movewaypoints"]="";
	m_values["moveextra"]="";
	m_values["movetimes"]="";
	m_values["updownwaypoints"]="";
	m_values["updownextra"]="";
	m_values["updowntimes"]="";
	m_values["debug"]="";

	//------NEW-----------
	m_values["rootindex"]="";	
	m_values["modelfile"]="";	//NEW
	m_values["rotation"]="";

	m_values["type"]="";
	m_values["speed"]="";
	m_values["gender"];
	m_values["alive"];
	m_values["stamina"];
	m_values["hunger"];
	m_values["digestion_rate"];
	m_values["nutritional_value"];
	m_values["feeding_distance"];
	m_values["see_radius"];
	m_values["hear_radius"];
	m_values["smell_radius"];
	m_values["agility"];
	m_values["age"];
	m_values["life_span"];
	m_values["prefered_separation"];
	m_values["keepaway_distance"];
	m_values["reproduct_rate"];

	SetAllFalse();
}

int CParamHandler::GetSegments()
{
	return GetInt(m_values["segments"]);
}



vector<float> CParamHandler::GetLengths()
{
	return GetFloatVector(m_values["lengths"]);
}

vector<float> CParamHandler::GetSpeed()
{
	return GetFloatVector(m_values["speed"]);
}

vector<float> CParamHandler::GetStamina()
{
	return GetFloatVector(m_values["stamina"]);
}

vector<float*> CParamHandler::GetWidths()
{
	return GetTwoFloatArrays(m_values["widths"]);
}

vector<float*> CParamHandler::GetHeights()
{
	return GetTwoFloatArrays(m_values["heights"]);
}

int CParamHandler::GetTailType()
{
	return GetInt(m_values["tailtype"]);
}

char** CParamHandler::GetMusclesUsage(int &no)
{
	return GetCharPtrPtr(m_values["muscles"],no);
}

Vector3 CParamHandler::GetPartsInfo()
{
	return GetVector(m_values["particle"]);
}

Vector3 CParamHandler::GetConnectionsInfo()
{
	return GetVector(m_values["connection"]);
}

float CParamHandler::GetWaterPressure()
{
	return GetFloat(m_values["waterpress"]);
}

Vector3 CParamHandler::GetStabilizer()
{
	return GetVector(m_values["stabilizer"]);
}

int CParamHandler::GetAcrobatics()
{
	return GetInt(m_values["acrobatics"]);
}

Vector3 CParamHandler::GetPosition()
{
	return GetVector(m_values["position"]);
}

Vector3 CParamHandler::GetRotation()
{
	return GetVector(m_values["rotation"]);
}

Vector3 CParamHandler::GetScale()
{
	return GetVector(m_values["scale"]);
}

float CParamHandler::GetLoses()
{
	return GetFloat(m_values["loses"]);
}

float CParamHandler::GetTextureExtra()
{
	return GetFloat(m_values["textureextra"]);
}

string CParamHandler::GetTexturePath()
{
	return m_values["texturepath"];
}

std::string CParamHandler::GetType()
{
	return m_values["type"];
}

Vector3 CParamHandler::GetTextureScale()
{
	return GetVector(m_values["texturescale"]);
}

Vector3 CParamHandler::GetTextureMove()
{
	return GetVector(m_values["texturemove"]);
}

vector<float> CParamHandler::GetWayPoints(const string &which)
{
	string which2 = which;
	which2 += "waypoints";
	return GetFloatVector(m_values[which2]);
}

vector<float> CParamHandler::GetTimes(const string &which)
{
	string which2 = which;
	which2 += "times"; 
	return GetFloatVector(m_values[which2]);
}

vector<float> CParamHandler::GetExtra(const string &which)
{
	string which2 = which;
	which2 += "extra"; 
	return GetFloatVector(m_values[which2]);
}

string CParamHandler::GetModelFile()
{
	return m_values["modelfile"];
}

int CParamHandler::GetRootIndex()
{
	return GetInt(m_values["rootindex"]);
}	




bool CParamHandler::IsTrue(const string &param)
{
	if (m_parameters.find(param)==m_parameters.end())
	{
		// not such a parameter in m_parameters....	
		return false;
	}
	return m_parameters[param];
}


void CParamHandler::SetTrue(const string &param)
{
	if(m_parameters.find(param) == m_parameters.end())
	{
		// not such a parameter in m_parameters....	
		return;
	}
	SetAllFalse();
	m_parameters[param]=true;
}


void CParamHandler::Parse(const string &toParse)
{
	Reset();

	CTokenizerNoComments tokenizer(toParse);
	string token;
	int level=0;
	string lastParameter;

	while (tokenizer.nextToken())
	{
		token = tokenizer.getToken();

		if (token=="{")
		{
			++level;
			continue;
		}
		else if(token=="}")
		{
			if(level==2) //2 is closing no more values for this parameter
				SetAllFalse();

			--level;
			continue;
		}


		if(level==1)
		{
			lastParameter=token;
			SetTrue(token);
			continue;
		}

		if (level==2)
		{
			AddToValue(lastParameter,token);
		}
	}
}




std::string CParamHandler::GetGender()
{
	return m_values["gender"];
}

int CParamHandler::GetAlive()
{
	return GetInt(m_values["alive"]);
}

float CParamHandler::GetDigestionRate()
{
	return GetFloat(m_values["digestion_rate"]);
}

vector<float> CParamHandler::GetHunger()
{
	return GetFloatVector(m_values["hunger"]);
}

float CParamHandler::GetNutritionalValue()
{
	return GetFloat(m_values["nutritional_value"]);
}

float CParamHandler::GetFeedingDistance()
{
	return GetFloat(m_values["feeding_distance"]);
}

float CParamHandler::GetSeeRadius()
{
	return GetFloat(m_values["see_radius"]);
}

float CParamHandler::GetHearRadius()
{
	return GetFloat(m_values["hear_radius"]);
}

float CParamHandler::GetSmellRadius()
{
	return GetFloat(m_values["smell_radius"]);
}

float CParamHandler::GetAgility()
{
	return GetFloat(m_values["agility"]);
}

int CParamHandler::GetAge()
{
	return GetInt(m_values["age"]);
}

vector<float> CParamHandler::GetLifeSpan()
{
	return GetFloatVector(m_values["life_span"]);
}

float CParamHandler::GetSeparation()
{
	return GetFloat(m_values["prefered_separation"]);
}

float CParamHandler::GetKeepaway()
{
	return GetFloat(m_values["keepaway_distance"]);
}

float CParamHandler::GetReproductionRate()
{
	return GetFloat(m_values["reproduct_rate"]);
}



























